{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">作者 Chris Burns, Christophe Combelles, Emmanuelle Gouillart, Gaël Varoquaux"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**Python中的科学计算**\n",
    ">这里我们介绍Python语言。这里只会仅仅解决可以用于Numpy和Scipy的最低要求。想要更多的了解这门语言，请参考http://docs.python.org/tutorial 这个非常好的教程。也可以借助专门的图书，比如：http://diveintopython.org/.\n",
    "\n",
    "Python是一门**编程语言**，与C、Fortran、BASIC和PHP等等类似。Python的一些特性如下：\n",
    "\n",
    "- 一种*解释性*（不是编译）语言。与C或者Fortran等不同，Python代码在执行前不会编译。另外，Python可以**交互**使用：有许多的Python解释器，命令和脚本可以在其中执行。\n",
    "- 在**开源**证书下发布的免费软件：Python可以免费使用和分发，即使用于商用。\n",
    "- **多平台**：Python可以用于所有的主流操作系统，Windows、Linux/Unix、MacOS X, 甚至可能是你有手机操作系统等等。\n",
    "- 可读性很强的语言，有清晰不罗嗦的语法\n",
    "- 拥有大量高质量的包，可以应用于多种多样的应用，从网站框架到科学计算。\n",
    "- 非常简单的接口与其他语言交互，特别是C和C++\n",
    "- 稍后会介绍一些语言的其他特性。例如Python是面向对象的语言，包含动态类型（一个变量可以在程序过程中，可以包含不同的对象类型）。\n",
    "\n",
    "Python的特有特性的更多信息，请见：http://www.python.org/about/\n",
    "\n",
    "## 1.2.1 第一步\n",
    "启动**IPython** Shell(一个增强的Python交互Shell)：\n",
    "\n",
    "- 在Linux/Mac终端中输入“ipython”，或者在Windows cmd sheell，\n",
    "- 或者从菜单启动程序，即在[Python(x,y)](http://www.pythonxy.com/)或[EPD](http://www.enthought.com/products/epd.php)，如果你已经安装这些Python科学套装之一。\n",
    "\n",
    "如果你的电脑上还没有安装IPython，也可以选择其他Python shells，比如在终端中输入“Python”启动纯Python shell，或者Idle解释器。但是，我们建议使用IPython Shell，因为它增强特性，特别是对于科学计算。\n",
    "\n",
    "如果你已经启动了解释器，输入"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello, world!\n"
     ]
    }
   ],
   "source": [
    "print \"Hello, world!\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来就会显示信息\"Hello, world!\"。你已经执行了你的第一条Python命令，恭喜！\n",
    "\n",
    "你自己开始吧，输入下列命令"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 3\n",
    "b = 2*a\n",
    "type(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6\n"
     ]
    }
   ],
   "source": [
    "print b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "18"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a*b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "str"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = 'hello'\n",
    "type(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hellohello'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hellohello'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2*b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面定义了*a*和*b*两个变量。注意这里在赋值前没有声明变量类型。相反，在C中，应该写为：\n",
    "```C\n",
    "int a=3;\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "另外，变量的类型可以改变，在一个时间点它可以等于一个特定类型，在接下来的时间里，他可以等于另外的类型。*b*首先等于整数，但是当它被赋值为*\"hello\"*时他变成等于字符。在Python中，整数的运算符（b＝2\\*a）原生支持的，一些字符上的操作符例如相加和相乘也是支持的，相当于串联和重复。\n",
    "## 1.2.2 基础类型\n",
    "### 1.2.2.1 数值类型\n",
    "\n",
    "Python支持如下的数值、标量类型：\n",
    "\n",
    "**整型：**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 4\n",
    "type(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**浮点型：**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "float"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = 2.1\n",
    "type(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**复数：**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.5"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 1.5 + 0.5j\n",
    "a.real"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.imag"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "complex"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(1. + 0j )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**布尔：**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "3 > 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test = (3 > 4)\n",
    "test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "bool"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "因此，Python shell可以代替你的口袋计算器，因为基本的代数操作符 +、-、\\*、/、%（模）都已经原生实现了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "21.0"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "7 * 3."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1024"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2**10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "8 % 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "类型转化（投射）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "**注意**：整数相除"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "3 / 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**技巧**：使用浮点："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.5"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "3 / 2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 3\n",
    "b = 2\n",
    "a / b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.5"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a / float(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果你明确想要整除，请使用//："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "3.0 // 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python3改变了除运算符行为。细节请看[python3porting](http://python3porting.com/preparing.html#use-instead-of-when-dividing-integers)网站.\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.2.2 容器\n",
    "Python提供了许多有效的容器类型，其中存储了对象集合。\n",
    "#### 1.2.2.2.1 列表\n",
    "列表是一个有序的对象集合，对象可以有多种类型。例如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "list"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L = ['red', 'blue', 'green', 'black', 'white']\n",
    "type(L)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "索引：访问包含在列表中的单个对象："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'green'"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L[2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用负索引，从结尾开始计数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'white'"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'black'"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L[-2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注意：索引从0开始**（和C中一样），而不是1（像在Fortran或Matlab）！\n",
    "\n",
    "切片：获得规律分布元素的子列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'blue', 'green', 'black', 'white']"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['green', 'black']"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L[2:4]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注意**：L[start:stop]包含索引start<= i < stop的元素（i的范围从start到stop-1）。因此，L[start:stop]包含（stop-start）个元素。\n",
    "\n",
    "**切片语法**：```L[start:stop:stride]```\n",
    "\n",
    "所有切片参数都是可选的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'blue', 'green', 'black', 'white']"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['black', 'white']"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L[3:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'blue', 'green']"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L[:3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表是可变对象，可以被改变："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['yellow', 'blue', 'green', 'black', 'white']"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L[0] = 'yellow'\n",
    "L "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['yellow', 'blue', 'gray', 'purple', 'white']"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L[2:4] = ['gray', 'purple']\n",
    "L"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注：**一个列表的元素可以有不同的类型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, -200, 'hello']"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L = [3, -200, 'hello']\n",
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-200, 'hello')"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L[1], L[2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于一个所有类型都相同的数值数据集合，使用Numpy模块提供的数组类型通常更有效。Numpy数组是包含固定大小项目的内存组块。使用Numpy数组，元素上的操作可以非常快速，因为元素均匀分布在内存上并且更多的操作是通过特殊的C函数而不是Python循环。\n",
    "\n",
    "Python提供了一大组函数来修改或查询列表。这里是一些例子，更多内容，请见：http://docs.python.org/tutorial/datastructures.html#more-on-lists\n",
    "\n",
    "添加和删除元素："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'blue', 'green', 'black', 'white', 'pink']"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L = ['red', 'blue', 'green', 'black', 'white']\n",
    "L.append('pink')\n",
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'pink'"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L.pop() # 删除并返回最后一个项目"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'blue', 'green', 'black', 'white']"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [],
   "source": [
    "L.extend(['pink', 'purple']) # 扩展列表L，原地\n",
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'blue', 'green', 'black', 'white']"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L = L[:-2]\n",
    "L"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "反转："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['white', 'black', 'green', 'blue', 'red']"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r = L[::-1]\n",
    "r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'blue', 'green', 'black', 'white']"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r2 = list(L)\n",
    "r2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['white', 'black', 'green', 'blue', 'red']"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r2.reverse() # 原对象\n",
    "r2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "串联和重复列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['white',\n",
       " 'black',\n",
       " 'green',\n",
       " 'blue',\n",
       " 'red',\n",
       " 'red',\n",
       " 'blue',\n",
       " 'green',\n",
       " 'black',\n",
       " 'white']"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r + L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['white',\n",
       " 'black',\n",
       " 'green',\n",
       " 'blue',\n",
       " 'red',\n",
       " 'white',\n",
       " 'black',\n",
       " 'green',\n",
       " 'blue',\n",
       " 'red']"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r * 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "排序："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['black', 'blue', 'green', 'red', 'white']"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sorted(r) # 新对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['white', 'black', 'green', 'blue', 'red']"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['black', 'blue', 'green', 'red', 'white']"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r.sort() # 原对象\n",
    "r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "**方法和面向对象编程**\n",
    "\n",
    "符号r.method() (即 r.append(3) and L.pop()) 是我们第一个关于面向对象编程的例子（OOP）。作为列表，对象r有可以以这种方式调用的方法函数。对于这篇教程不需要关于面向对象编程的更多知识，只需要理解这种符号。\n",
    "\n",
    "---\n",
    "**发现方法**：\n",
    "\n",
    "提醒：在IPython中：tab完成 (按tab)\n",
    "\n",
    "```python\n",
    "In [28]: r.<TAB>\n",
    "r.__add__           r.__iadd__        r.__setattr__\n",
    "r.__class__         r.__imul__        r.__setitem__\n",
    "r.__contains__      r.__init__        r.__setslice__\n",
    "r.__delattr__       r.__iter__        r.__sizeof__\n",
    "r.__delitem__       r.__le__          r.__str__\n",
    "r.__delslice__      r.__len__         r.__subclasshook__\n",
    "r.__doc__           r.__lt__          r.append\n",
    "r.__eq__            r.__mul__         r.count\n",
    "r.__format__        r.__ne__          r.extend\n",
    "r.__ge__            r.__new__         r.index\n",
    "r.__getattribute__  r.__reduce__      r.insert\n",
    "r.__getitem__       r.__reduce_ex__   r.pop\n",
    "r.__getslice__      r.__repr__        r.remove\n",
    "r.__gt__            r.__reversed__    r.reverse\n",
    "r.__hash__          r.__rmul__        r.sort\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.2.2.2 字符\n",
    "\n",
    "不同的字符语法（单引号、双引号或三个引号）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-58-dfe00f996c26>, line 7)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-58-dfe00f996c26>\"\u001b[0;36m, line \u001b[0;32m7\u001b[0m\n\u001b[0;31m    'Hi, what's up?'\u001b[0m\n\u001b[0m              ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "s = 'Hello, how are you?'\n",
    "s = \"Hi, what's up\"\n",
    "s = '''Hello,                 \n",
    "       how are you'''         # 三个引号可以允许字符跨行\n",
    "s = \"\"\"Hi,\n",
    "what's up?\"\"\"\n",
    "'Hi, what's up?'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果在字符中要是使用引号，那么应该嵌套使用，或者使用\"\\\"进行转义，否则会报错。\n",
    "\n",
    "换行的符号为 \\n，tab符号是\\t。\n",
    "\n",
    "字符也是类似与列表的结合。因此，也可以使用相同的语法和规则索引和切片。\n",
    "\n",
    "索引："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'h'"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = \"hello\"\n",
    "a[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'e'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'o'"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（记住负索引从右侧开始计数。）\n",
    "\n",
    "切片："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'lo,'"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = \"hello, world!\"\n",
    "a[3:6] # 第三到第六个（不包含）元素：元素3、4、5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'lo o'"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[2:10:2] # 语法：a[开始：结束：步幅]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hl r!'"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[::3] # 从开始到结尾，每隔3个字母"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "重音符号和特殊字符也可以被处理为Unicode字符（请见 http://docs.python.org/tutorial/introduction.html#unicode-strings）。\n",
    "\n",
    "字符是**不可变**对象，不可能修改内容。不过可以从原始的字符中创建一个新的字符。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'str' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-68-8f124c87c8cf>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"hello, world!\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'z'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "a = \"hello, world!\"\n",
    "a[2] = 'z'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hezlo, world!'"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.replace('l', 'z', 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hezzo, worzd!'"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.replace('l', 'z')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字符有许多有用的方法，比如上面的a.replace。回忆一下a.面向对象的符号，并且使用tab完成或者help(str)来搜索新的方法。\n",
    "\n",
    "**更多内容** Python提供了操作的字符的高级可能性，看一下模式或格式。感兴趣的读者请参考：http://docs.python.org/library/stdtypes.html#string-methods 和 http://docs.python.org/library/string.html#new-string-formatting。\n",
    "\n",
    "字符格式："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'An integer: 1; a float: 0.100000; another string: string'"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'An integer: %i; a float: %f; another string: %s' % (1, 0.1, 'string')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'processing_of_dataset_102.txt'"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "i = 102\n",
    "filename = 'processing_of_dataset_%d.txt' % i\n",
    "filename"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.2.2.3. Dictionaries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字典本质上是一个**映射键值**的高效表格。它是一个**无序**的容器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'emmanuelle': 5752, 'francis': 5915, 'sebastian': 5578}"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tel = {'emmanuelle': 5752, 'sebastian': 5578}\n",
    "tel['francis'] = 5915\n",
    "tel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5578"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tel['sebastian']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['sebastian', 'francis', 'emmanuelle']"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tel.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5578, 5915, 5752]"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tel.values()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "它可以方便的以名字（日期的字符和名称等）存储和获取值。更多信息见 http://docs.python.org/tutorial/datastructures.html#dictionaries。\n",
    "\n",
    "一个字典的键（代表值）可以有不同的类型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{3: 'hello', 'a': 1, 'b': 2}"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = {'a':1, 'b':2, 3:'hello'}\n",
    "d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.2.2.4. More container types\n",
    "\n",
    "**元组**\n",
    "\n",
    "元组本质上是不可变列表。元组的元素用括号包起来，或者只是用逗号分割："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12345"
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t = 12345, 54321, 'hello!'\n",
    "t[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(12345, 54321, 'hello!')"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [],
   "source": [
    "u = (0, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**集合**：无序，惟一项目："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a', 'b', 'c'}"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = set(('a', 'b', 'c', 'a'))\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'c'}"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.difference(('a', 'b'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.2.3. 赋值运算"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Python类库参考：](http://docs.python.org/reference/simple_stmts.html#assignment-statements)\n",
    "\n",
    ">赋值语句被用于（重）绑定名称与值，以及修改可变对象的项目或属性。\n",
    "\n",
    "简单来说，它这样工作（简单赋值）：\n",
    "\n",
    "1. 右侧表达式被评估，创建或获得产生的对象\n",
    "\n",
    "2. 左侧的名字被赋值或绑定到右侧的对象\n",
    "\n",
    "需要注意的事情：\n",
    "\n",
    "- 单个对象可以有多个绑定的名称："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3]"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [1, 2, 3]\n",
    "b = a\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3]"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a is b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 'hi!', 3]"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[1] = 'hi!'\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 要在**原地**改变列表，请使用索引或切片："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3]"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [1, 2, 3]\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['a', 'b', 'c']"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = ['a', 'b', 'c'] # 创建另一个对象\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4394695640"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "id(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3]"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[:] = [1, 2, 3] # 在原地修改对象\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4394695640"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "id(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "与上一个id相同，你的可能有所不同..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 这里的关键观点是可变 vs. 不可变\n",
    "\n",
    "    - 可变对象可以在原地修改\n",
    "    - 不可变对象一旦被创建就不可修改\n",
    "\n",
    "**更多内容**在David M. Beazley的文章[Python中的类型和对象](http://www.informit.com/articles/article.aspx?p=453682)中也可以找到关于以上问题非常不错的详尽解释。\n",
    "## 1.2.3 流程控制\n",
    "\n",
    "控制代码执行顺序。\n",
    "\n",
    "### 1.2.3.1 if/elif/else"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Obvious!\n"
     ]
    }
   ],
   "source": [
    "if 2**2 == 4:\n",
    "    print 'Obvious!'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**代码块用缩进限定**\n",
    "\n",
    "---\n",
    "\n",
    "**小技巧**：在你的Python解释器内输入下列行，并且注意保持缩进深度。IPython shell会在一行的 : 符号后自动增加缩进，如果要减少缩进，向左侧移动4个空格使用后退键。按两次回车键离开逻辑块。\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A lot\n"
     ]
    }
   ],
   "source": [
    "a = 10\n",
    "if a == 1:\n",
    "    print(1)\n",
    "elif a == 2:\n",
    "    print(2)\n",
    "else:\n",
    "    print('A lot')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在脚本中也是强制缩进的。作为练习，在condition.py脚本中以相同的缩进重新输入之前几行，并在IPython中用```run condition.py```执行脚本。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.3.2 for/range\n",
    "\n",
    "在索引上迭代："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "for i in range(4):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是最经常使用，也更易读的是在值上迭代："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Python is cool\n",
      "Python is powerful\n",
      "Python is readable\n"
     ]
    }
   ],
   "source": [
    "for word in ('cool', 'powerful', 'readable'):\n",
    "    print('Python is %s' % word)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.3.3 while/break/continue\n",
    "\n",
    "典型的C式While循环（Mandelbrot问题）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-134+352j)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = 1 + 1j\n",
    "while abs(z) < 100: \n",
    "    z = z**2 + 1\n",
    "z"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**更高级的功能**\n",
    "\n",
    "break 跳出for/while循环："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1+2j)\n",
      "(-2+4j)\n",
      "(-11-16j)\n",
      "(-134+352j)\n"
     ]
    }
   ],
   "source": [
    "z = 1 + 1j\n",
    "while abs(z) < 100:\n",
    "    if z.imag == 0:\n",
    "        break\n",
    "    z = z**2 + 1\n",
    "    print z"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "continue 继续下一个循环迭代："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0\n",
      "0.5\n",
      "0.25\n"
     ]
    }
   ],
   "source": [
    "a = [1, 0, 2, 4]\n",
    "for element in a:\n",
    "    if element == 0:\n",
    "        continue\n",
    "    print 1. / element"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.3.4 条件表达式\n",
    "\n",
    "**if [OBJECT]：**\n",
    "\n",
    "评估为False：\n",
    "    - 任何等于0的数字 (0、0.0、0+0j)\n",
    "    - 空容器（列表、元组、集合、字典, ...）\n",
    "    - False，None\n",
    "\n",
    "评估为True：\n",
    "    - 任何其他的东西\n",
    "    \n",
    "**a == b：**\n",
    "\n",
    "判断逻辑是否相等："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 == 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**a is b：**\n",
    "\n",
    "测试同一性：两边是相同的对象："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 is 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 1\n",
    "b = 1\n",
    "a is b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**a in b：**\n",
    "\n",
    "对于任何集合b：b包含a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = [1, 2, 3]\n",
    "2 in b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "5 in b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果b是字典，这个语法测试a是否是b的一个键。\n",
    "\n",
    "### 1.2.3.5. 高级循环\n",
    "\n",
    "#### 1.2.3.5.1 序列循环\n",
    "\n",
    "你可以在任何序列上进行循环（字符、列表、字典的键，文件的行...）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "o e u\n"
     ]
    }
   ],
   "source": [
    "vowels = 'aeiouy'\n",
    "for i in 'powerful':\n",
    "    if i in vowels:\n",
    "        print(i),"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Hello', 'how', 'are', 'you?']"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "message = \"Hello how are you?\"\n",
    "message.split() # 返回一个列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello\n",
      "how\n",
      "are\n",
      "you?\n"
     ]
    }
   ],
   "source": [
    "for word in message.split():\n",
    "    print word"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "很少有语言（特别是科学计算语言）允许在整数或索引之外的循环。在Python中，可以在感兴趣的对象上循环，而不用担心你通常不关心的索引。这个功能通常用来让代码更易读。\n",
    "\n",
    "**警告**：改变正在循环的序列是不安全的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.3.5.2 跟踪列举数\n",
    "\n",
    "通常任务是在一个序列上循环，同时跟踪项目数。\n",
    "    - 可以像上面，使用带有计数器的while循环。或者一个for循环："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 cool\n",
      "1 powerful\n",
      "2 readable\n"
     ]
    }
   ],
   "source": [
    "words = ('cool', 'powerful', 'readable')\n",
    "for i in range(0, len(words)):\n",
    "    print i, words[i]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是，Python为这种情况提供了enumerate关键词："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 cool\n",
      "1 powerful\n",
      "2 readable\n"
     ]
    }
   ],
   "source": [
    "for index, item in enumerate(words):\n",
    "    print index, item"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.3.5.3 字典循环\n",
    "\n",
    "使用**iteritems**："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Key: a has value: 1\n",
      "Key: c has value: 1j\n",
      "Key: b has value: 1.2\n"
     ]
    }
   ],
   "source": [
    "d = {'a': 1, 'b':1.2, 'c':1j}\n",
    "for key, val in d.iteritems():\n",
    "    print('Key: %s has value: %s' % (key, val))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.3.5.4 列表推导式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 4, 9]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[i**2 for i in range(4)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "**练习**\n",
    "\n",
    "用Wallis公式，计算π的小数\n",
    "\n",
    "![Wallis公式](http://scipy-lectures.github.io/_images/math/31913b3982be13ed2063b0ffccbcab9cf4931fdb.png)\n",
    "\n",
    "---\n",
    "\n",
    "## 1.2.4. 定义函数\n",
    "\n",
    "### 1.2.4.1 函数的定义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "in test function\n"
     ]
    }
   ],
   "source": [
    "def test():\n",
    "    print('in test function')\n",
    "\n",
    "test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注意**：函数块必须像其他流程控制块一样缩进\n",
    "\n",
    "### 1.2.4.2 返回语句\n",
    "\n",
    "函数**可以选择**返回值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7.0649999999999995"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def disk_area(radius):\n",
    "    return 3.14 * radius * radius\n",
    "\n",
    "disk_area(1.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注意**：默认函数返回`None`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注意**：注意定义函数的语法：\n",
    "\n",
    "- def关键字：\n",
    "- 接下来是函数的名称，然后\n",
    "- 是在圆括号中的函数的参数，并跟着一个冒号。\n",
    "- 函数体；\n",
    "- 以及可选返回值的返回对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.4.3 参数\n",
    "\n",
    "必选参数（位置参数）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def double_it(x):\n",
    "    return x * 2\n",
    "\n",
    "double_it(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "double_it() takes exactly 1 argument (0 given)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-25-51cdedbb81b0>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdouble_it\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m: double_it() takes exactly 1 argument (0 given)"
     ]
    }
   ],
   "source": [
    "double_it()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可选参数（关键词和命名参数）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def double_it(x=2):\n",
    "    return x * 2\n",
    "\n",
    "double_it()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "double_it(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "关键词参数允许你设置特定默认值。\n",
    "\n",
    "**警告：**默认值在函数定义时被评估，而不是在调用时。如果使用可变类型（即字典或列表）并在函数体内修改他们，这可能会产生问题，因为这个修改会在函数被引用的时候一直持续存在。\n",
    "\n",
    "在关键词参数中使用不可变类型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bigx = 10\n",
    "def double_it(x=bigx):\n",
    "    return x * 2\n",
    "bigx = 1e9  # 现在真的非常大\n",
    "double_it()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在关键词参数中使用可变类型（并且在函数体内修改它）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<function __main__.add_to_dict>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def add_to_dict(args={'a': 1, 'b': 2}):\n",
    "    for i in args.keys():\n",
    "        args[i] += 1\n",
    "    print args\n",
    "\n",
    "add_to_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 2, 'b': 3}\n"
     ]
    }
   ],
   "source": [
    "add_to_dict()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 3, 'b': 4}\n"
     ]
    }
   ],
   "source": [
    "add_to_dict()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 4, 'b': 5}\n"
     ]
    }
   ],
   "source": [
    "add_to_dict()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "更复杂的例子，实现Python的切片："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['one', 'fish,', 'two', 'fish,', 'red', 'fish,', 'blue', 'fish']"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def slicer(seq, start=None, stop=None, step=None):\n",
    "    \"\"\"Implement basic python slicing.\"\"\"\n",
    "    return seq[start:stop:step]\n",
    "\n",
    "rhyme = 'one fish, two fish, red fish, blue fish'.split()\n",
    "\n",
    "rhyme"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['one', 'fish,', 'two', 'fish,', 'red', 'fish,', 'blue', 'fish']"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "slicer(rhyme)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['one', 'two', 'red', 'blue']"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "slicer(rhyme, step=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['fish,', 'fish,', 'fish,', 'fish']"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "slicer(rhyme, 1, step=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['fish,', 'fish,']"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "slicer(rhyme, start=1, stop=4, step=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "关键词参数的顺序**不**重要："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['fish,', 'fish,']"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "slicer(rhyme, step=2, start=1, stop=4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是，最好是使用与函数定义相同的顺序。\n",
    "\n",
    "*关键词参数*是特别方便的功能，可以用可变数量的参数来定义一个函数，特别是当函数据绝大多数调用都会使用默认值时。\n",
    "\n",
    "### 1.2.4.4 值传递"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以在一个函数内部改变变量的值吗？大多数语言（C、Java...）区分了“值传递“和”引用传递“。在Python中，没有严格的这种区分，并且视你的变量是否会修改而有一些不同。幸运的是，这些情况存在明确的规则。\n",
    "\n",
    "函数的参数是对象的引用，传递的是值。当你向一个函数传递了一个变量，Python传递的是对象的引用，这个对象引用的变量（值）。而不是变量本身。\n",
    "\n",
    "如果**值**传递给函数的值是不可变的，那么这个函数并不会改变调用者的变量。如果**值**是可变的，那么函数将可能在原地修改调用者的变量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "23\n",
      "[99, 42]\n",
      "[99]\n"
     ]
    }
   ],
   "source": [
    "def try_to_modify(x, y, z):\n",
    "    x = 23\n",
    "    y.append(42)\n",
    "    z = [99] # 新引用\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "\n",
    "a = 77    # 不可变变量\n",
    "b = [99]  # 可变变量\n",
    "c = [28]\n",
    "try_to_modify(a, b, c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "77\n"
     ]
    }
   ],
   "source": [
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[99, 42]\n"
     ]
    }
   ],
   "source": [
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[28]\n"
     ]
    }
   ],
   "source": [
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "函数有名为*local namespace*的本地变量表。\n",
    "\n",
    "变量X只存在于函数try_to_modify内部。\n",
    "\n",
    "### 1.2.4.5 全局变量\n",
    "\n",
    "在函数外定义的变量可以在函数内引用："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = 5\n",
    "def addx(y):\n",
    "    return x + y\n",
    "\n",
    "addx(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是，这些全局变量不能在函数内修改，除非在函数内声明**global**。\n",
    "\n",
    "这样没用："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is 10\n"
     ]
    }
   ],
   "source": [
    "def setx(y):\n",
    "    x = y\n",
    "    print('x is %d' % x)\n",
    "\n",
    "setx(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这样可以："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x is 10\n"
     ]
    }
   ],
   "source": [
    "def setx(y):\n",
    "    global x\n",
    "    x = y\n",
    "    print('x is %d' % x)\n",
    "\n",
    "setx(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.4.6 可变数量参数\n",
    "\n",
    "函数的特殊形式：\n",
    "    - *args：封装成元组的任意数量的位置参数\n",
    "    - **kwargs：封装成字典的任意数量的关键词参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "args is ('one', 'two')\n",
      "kwargs is {'y': 2, 'x': 1, 'z': 3}\n"
     ]
    }
   ],
   "source": [
    "def variable_args(*args, **kwargs):\n",
    "    print 'args is', args\n",
    "    print 'kwargs is', kwargs\n",
    "\n",
    "variable_args('one', 'two', x=1, y=2, z=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.4.7 Docstrings\n",
    "\n",
    "关于函数作用及参数的文档。通常惯例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [],
   "source": [
    "def funcname(params):\n",
    "    \"\"\"Concise one-line sentence describing the function.\n",
    "    Extended summary which can contain multiple paragraphs.\n",
    "    \"\"\"\n",
    "    # 函数体\n",
    "    pass\n",
    "\n",
    "funcname?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "Type:           function\n",
    "Base Class:     type 'function'>\n",
    "String Form:    <function funcname at 0xeaa0f0>\n",
    "Namespace:      Interactive\n",
    "File:           <ipython console>\n",
    "Definition:     funcname(params)\n",
    "Docstring:\n",
    "    Concise one-line sentence describing the function.\n",
    "\n",
    "    Extended summary which can contain multiple paragraphs.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注 Docstring 指导**\n",
    "\n",
    "为了标准化，[Docstring规范](https://www.python.org/dev/peps/pep-0257)页面为Python Docstring相关的含义及书写规范提供了文档。\n",
    "\n",
    "Numpy和Scipy模块也为科学计算函数定义了清晰的标准，你可能想要在自己的函数中去遵循，这个标准有参数部分，例子部分等。见http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard 及 http://projects.scipy.org/numpy/browser/trunk/doc/example.py#L37"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.4.8 函数作为对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "函数是一级对象，这意味着他们可以是：\n",
    "    \n",
    "    - 可以被赋值给变量\n",
    "    - 列表的一个项目（或任何集合）\n",
    "    - 作为参数传递给另一个函数\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "run_control": {
     "frozen": false,
     "read_only": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "args is ('three',)\n",
      "kwargs is {'y': 2, 'x': 1}\n"
     ]
    }
   ],
   "source": [
    "va = variable_args\n",
    "\n",
    "va('three', x=1, y=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.4.9 方法\n",
    "\n",
    "方法是对象的函数。你已经在我们关于列表、字典和字符等...的例子上看到了。\n",
    "\n",
    "### 1.2.4.10. 练习\n",
    "\n",
    "**练习：斐波那契数列**\n",
    "\n",
    "写一个函数来展示斐波那契数列的前n个项目，定义如下：\n",
    "    - u_0 = 1; u_1 = 1\n",
    "    - u_(n+2) = u_(n+1) + u_n\n",
    "   \n",
    "**练习：快速排序**\n",
    "\n",
    "实现快速排序算法，定义来自wikipedia：\n",
    "\n",
    "function quicksort(array)\n",
    "    \n",
    "    var list less, greater if length(array) < 2\n",
    "    \n",
    "        return array\n",
    "    \n",
    "    select and remove a pivot value pivot from array for each x in array\n",
    "\n",
    "        if x < pivot + 1 then append x to less else append x to greater\n",
    "\n",
    "    return concatenate(quicksort(less), pivot, quicksort(greater))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
